home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / hlrad / mathutil.cpp < prev    next >
C/C++ Source or Header  |  2002-12-08  |  9KB  |  287 lines

  1. #include "qrad.h"
  2.  
  3. // =====================================================================================
  4. //  point_in_winding
  5. // =====================================================================================
  6. bool            point_in_winding(const Winding& w, const dplane_t& plane, const vec_t* const point)
  7. {
  8.     unsigned        numpoints = w.m_NumPoints;
  9.     int             x;
  10.  
  11.     for (x = 0; x < numpoints; x++)
  12.     {
  13.         vec3_t          A;
  14.         vec3_t          B;
  15.         vec3_t          normal;
  16.  
  17.         VectorSubtract(w.m_Points[(x + 1) % numpoints], point, A);
  18.         VectorSubtract(w.m_Points[x], point, B);
  19.         CrossProduct(A, B, normal);
  20.         VectorNormalize(normal);
  21.  
  22.         if (DotProduct(normal, plane.normal) < 0.0)
  23.         {
  24.             return false;
  25.         }
  26.     }
  27.  
  28.     return true;
  29. }
  30.  
  31. // =====================================================================================
  32. //  point_in_wall
  33. // =====================================================================================
  34. bool            point_in_wall(const lerpWall_t* wall, vec3_t point)
  35. {
  36.     int             x;
  37.  
  38.     // Liberal use of the magic number '4' for the hardcoded winding count
  39.     for (x = 0; x < 4; x++)
  40.     {
  41.         vec3_t          A;
  42.         vec3_t          B;
  43.         vec3_t          normal;
  44.  
  45.         VectorSubtract(wall->vertex[x], wall->vertex[(x + 1) % 4], A);
  46.         VectorSubtract(wall->vertex[x], point, B);
  47.         CrossProduct(A, B, normal);
  48.         VectorNormalize(normal);
  49.  
  50.         if (DotProduct(normal, wall->plane.normal) < 0.0)
  51.         {
  52.             return false;
  53.         }
  54.     }
  55.     return true;
  56. }
  57.  
  58. // =====================================================================================
  59. //  point_in_tri
  60. // =====================================================================================
  61. bool            point_in_tri(const vec3_t point, const dplane_t* const plane, const vec3_t p1, const vec3_t p2, const vec3_t p3)
  62. {
  63.     vec3_t          A;
  64.     vec3_t          B;
  65.     vec3_t          normal;
  66.  
  67.     VectorSubtract(p1, p2, A);
  68.     VectorSubtract(p1, point, B);
  69.     CrossProduct(A, B, normal);
  70.     VectorNormalize(normal);
  71.  
  72.     if (DotProduct(normal, plane->normal) < 0.0)
  73.     {
  74.         return false;
  75.     }
  76.  
  77.     VectorSubtract(p2, p3, A);
  78.     VectorSubtract(p2, point, B);
  79.     CrossProduct(A, B, normal);
  80.     VectorNormalize(normal);
  81.  
  82.     if (DotProduct(normal, plane->normal) < 0.0)
  83.     {
  84.         return false;
  85.     }
  86.  
  87.     VectorSubtract(p3, p1, A);
  88.     VectorSubtract(p3, point, B);
  89.     CrossProduct(A, B, normal);
  90.     VectorNormalize(normal);
  91.  
  92.     if (DotProduct(normal, plane->normal) < 0.0)
  93.     {
  94.         return false;
  95.     }
  96.     return true;
  97. }
  98.  
  99. // =====================================================================================
  100. //  intersect_line_plane
  101. //      returns true if line hits plane, and parameter 'point' is filled with where
  102. // =====================================================================================
  103. bool            intersect_line_plane(const dplane_t* const plane, const vec_t* const p1, const vec_t* const p2, vec3_t point)
  104. {
  105.     vec3_t          pop;
  106.     vec3_t          line_vector;                           // normalized vector for the line;
  107.     vec3_t          tmp;
  108.     vec3_t          scaledDir;
  109.     vec_t           partial;
  110.     vec_t           total;
  111.     vec_t           perc;
  112.  
  113.     // Get a normalized vector for the ray
  114.     VectorSubtract(p1, p2, line_vector);
  115.     VectorNormalize(line_vector);
  116.  
  117.     VectorScale(plane->normal, plane->dist, pop);
  118.     VectorSubtract(pop, p1, tmp);
  119.     partial = DotProduct(tmp, plane->normal);
  120.     total = DotProduct(line_vector, plane->normal);
  121.  
  122.     if (total == 0.0)
  123.     {
  124.         VectorClear(point);
  125.         return false;
  126.     }
  127.  
  128.     perc = partial / total;
  129.     VectorScale(line_vector, perc, scaledDir);
  130.     VectorAdd(p1, scaledDir, point);
  131.     return true;
  132. }
  133.  
  134. // =====================================================================================
  135. //  intersect_linesegment_plane
  136. //      returns true if line hits plane, and parameter 'point' is filled with where
  137. // =====================================================================================
  138. bool            intersect_linesegment_plane(const dplane_t* const plane, const vec_t* const p1, const vec_t* const p2, vec3_t point)
  139. {
  140.     unsigned        count = 0;
  141.  
  142.     if (DotProduct(plane->normal, p1) <= plane->dist)
  143.     {
  144.         count++;
  145.     }
  146.     if (DotProduct(plane->normal, p2) <= plane->dist)
  147.     {
  148.         count++;
  149.     }
  150.  
  151.     if (count == 1)
  152.     {
  153.         return intersect_line_plane(plane, p1, p2, point);
  154.     }
  155.     else
  156.     {
  157.         return false;
  158.     }
  159. }
  160.  
  161. // =====================================================================================
  162. //  plane_from_points
  163. // =====================================================================================
  164. void            plane_from_points(const vec3_t p1, const vec3_t p2, const vec3_t p3, dplane_t* plane)
  165. {
  166.     vec3_t          delta1;
  167.     vec3_t          delta2;
  168.     vec3_t          normal;
  169.  
  170.     VectorSubtract(p3, p2, delta1);
  171.     VectorSubtract(p1, p2, delta2);
  172.     CrossProduct(delta1, delta2, normal);
  173.     VectorNormalize(normal);
  174.     plane->dist = DotProduct(normal, p1);
  175.     VectorCopy(normal, plane->normal);
  176. }
  177.  
  178. // =====================================================================================
  179. //  TestSegmentAgainstOpaqueList
  180. //      Returns true if the segment intersects an item in the opaque list
  181. // =====================================================================================
  182. #ifdef HLRAD_HULLU
  183. bool            TestSegmentAgainstOpaqueList(const vec_t* p1, const vec_t* p2, vec3_t &scaleout)
  184. #else
  185. bool            TestSegmentAgainstOpaqueList(const vec_t* p1, const vec_t* p2)
  186. #endif
  187. {
  188.     unsigned        x;
  189.     vec3_t          point;
  190.     const dplane_t* plane;
  191.     const Winding*  winding;
  192.  
  193. #ifdef HLRAD_HULLU
  194.     vec3_t        scale = {1.0, 1.0, 1.0};
  195. #endif
  196.  
  197.     for (x = 0; x < g_opaque_face_count; x++)
  198.     {
  199.         plane = &g_opaque_face_list[x].plane;
  200.         winding = g_opaque_face_list[x].winding;
  201.  
  202. #ifdef HLRAD_OPACITY // AJM
  203.         l_opacity = g_opaque_face_list[x].l_opacity;
  204. #endif
  205.         if (intersect_linesegment_plane(plane, p1, p2, point))
  206.         {
  207. #if 0
  208.             Log
  209.                 ("Ray from (%4.3f %4.3f %4.3f) to (%4.3f %4.3f %4.3f) hits plane at (%4.3f %4.3f %4.3f)\n Plane (%4.3f %4.3f %4.3f) %4.3f\n",
  210.                  p1[0], p1[1], p1[2], p2[0], p2[1], p2[2], point[0], point[1], point[2], plane->normal[0],
  211.                  plane->normal[1], plane->normal[2], plane->dist);
  212. #endif
  213.             if (point_in_winding(*winding, *plane, point))
  214.             {
  215. #if 0
  216.                 Log("Ray from (%4.3f %4.3f %4.3f) to (%4.3f %4.3f %4.3f) blocked by face %u @ (%4.3f %4.3f %4.3f)\n",
  217.                     p1[0], p1[1], p1[2],
  218.                     p2[0], p2[1], p2[2], g_opaque_face_list[x].facenum, point[0], point[1], point[2]);
  219. #endif
  220.  
  221. #ifdef HLRAD_HULLU
  222.                 if(g_opaque_face_list[x].transparency)
  223.                 {
  224.                     VectorMultiply(scale, g_opaque_face_list[x].transparency_scale, scale);
  225.                 }
  226.                 else
  227.                 {
  228.                     VectorCopy(scale, scaleout);
  229.                     return true;
  230.                 }
  231. #else
  232.                 return true;
  233. #endif
  234.             }
  235.         }
  236.     }
  237.  
  238. #ifdef HLRAD_HULLU
  239.     VectorCopy(scale, scaleout);
  240.     if(scaleout[0] < 0.01 && scaleout[1] < 0.01 && scaleout[2] < 0.01)
  241.     {
  242.         return true; //so much shadowing that result is same as with normal opaque face
  243.     }
  244. #endif
  245.  
  246.     return false;
  247. }
  248.  
  249. // =====================================================================================
  250. //  ProjectionPoint
  251. // =====================================================================================
  252. void            ProjectionPoint(const vec_t* const v, const vec_t* const p, vec_t* rval)
  253. {
  254.     vec_t           val;
  255.     vec_t           mag;
  256.  
  257.     mag = DotProduct(p, p);
  258. #ifdef SYSTEM_POSIX
  259.     if (mag == 0)
  260.     {
  261.         // division by zero seems to work just fine on x86;
  262.         // it returns nan and the program still works!!
  263.         // this causes a floating point exception on Alphas, so...
  264.         mag = 0.00000001; 
  265.     }
  266. #endif
  267.     val = DotProduct(v, p) / mag;
  268.  
  269.     VectorScale(p, val, rval);
  270. }
  271.  
  272. // =====================================================================================
  273. //  SnapToPlane
  274. // =====================================================================================
  275. void            SnapToPlane(const dplane_t* const plane, vec_t* const point, vec_t offset)
  276. {
  277.     vec3_t          delta;
  278.     vec3_t          proj;
  279.     vec3_t          pop;                                   // point on plane
  280.  
  281.     VectorScale(plane->normal, plane->dist + offset, pop);
  282.     VectorSubtract(point, pop, delta);
  283.     ProjectionPoint(delta, plane->normal, proj);
  284.     VectorSubtract(delta, proj, delta);
  285.     VectorAdd(delta, pop, point);
  286. }
  287.